/*
 * Copyright (c) 2008, Solido Systems
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of Solido Systems nor the names of its contributors may be
 * used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.solidosystems.objectkitchen.test;

import com.solidosystems.objectkitchen.data.*;
import com.solidosystems.objectkitchen.storage.*;

import java.util.concurrent.*;
import java.util.*;
import java.io.*;
import java.sql.*;

public class BenchmarkThread implements Runnable{
	public final static int CREATE=0;
	public final static int READ=1;
	public final static int UPDATE=2;
	public final static int ATTACH=3;
	public final static int READATTACH=4;
	public final static int SCAN=5;
	public final static int SCRIPTUPDATE=6;
	public final static int SCRIPTQUERY=7;
	public final static int SQLADD=8;
	public final static int SQLREAD=9;
	public final static int SQLUPDATE=10;
	public final static int SQLSCAN=11;
	
	private BlockSet block;
	private int size;
	private int mode;
	private String id;
	private Connection dbcon;
	
	public BenchmarkThread(Connection dbcon,BlockSet block,String id,int size, int mode){
		this.block=block;
		this.size=size;
		this.mode=mode;
		this.id=id;
		this.dbcon=dbcon;
	}	
	
	public void run(){
		try{
			switch(mode){
				case CREATE :
						for(int i=0;i<size;i++){
							Document doc=block.getOrCreateDocument("/"+id+"/"+i);
							VHash hash=doc.getHash();
							hash.put("int-val",i);
							hash.put("str-val1",""+i);
							hash.put("str-val2",""+i);
							hash.put("str-val3",""+i);
							hash.put("str-val4",""+i);
							hash.put("tcreated",System.currentTimeMillis());
							block.putDocument(doc);
						}
					break;
				case READ :
						for(int i=0;i<size;i++){
							Document doc=block.getDocument("/"+id+"/"+((int)(Math.random()*size)));
							VHash hash=doc.getHash();
						}
					break;
				case UPDATE :
						for(int i=0;i<size;i++){
							Document doc=block.getDocument("/"+id+"/"+i);
							VHash hash=doc.getHash();
							hash.put("int-val",i+1);
							hash.put("tmodified",System.currentTimeMillis());
							block.putDocument(doc);
						}
					break;
				case ATTACH :
						byte[] buf=new byte[4096];
						for(int i=0;i<size;i++){
							block.putAttachment("/"+id+"/"+i,"test",buf);
						}
					break;
				case READATTACH :
						for(int i=0;i<size;i++){
							block.getAttachment("/"+id+"/"+i,"test");
						}
					break;
				case SCAN :
						List<String> lst= block.getGroupMembers("/"+id+"/");
						for(String id:lst){
							block.getDocument(id);
						}
					break;
				case SCRIPTUPDATE :
						block.executeUpdate("/"+id+"/","python","h=doc.getHash()\nh.put('int-val',h.getInteger('int-val')+1)");
					break;
				case SCRIPTQUERY :
						block.executeQuery("/"+id+"/","python","h=doc.getHash()\nif(h.getInteger('int-val')%2==1):\n  doc.setMatch(True)");
					break;
				case SQLADD :
					Statement st=dbcon.createStatement();
					for(int i=0;i<size;i++){
						st.executeUpdate("INSERT INTO tbl_test1 (id,grp,intval,strval1,strval2,strval3,strval4,tcreated) VALUES ('"+id+"-"+i+"','/"+id+"/',"+i+",'"+i+"','"+i+"','"+i+"','"+i+"',now())");
					}
					break;
				case SQLREAD :
					st=dbcon.createStatement();
					for(int i=0;i<size;i++){
						ResultSet rs=st.executeQuery("SELECT * FROM tbl_test1 WHERE id='"+id+"-"+((int)(Math.random()*size))+"'");
						while(rs.next()){
						
						}
						rs.close();
					}
					break;
				case SQLUPDATE :
					st=dbcon.createStatement();
					for(int i=0;i<size;i++){
						st.executeUpdate("UPDATE tbl_test1 SET intval=intval+1,tmodified=now() WHERE id='"+id+"-"+i+"'");
					}
					break;
				case SQLSCAN :
					st=dbcon.createStatement();
					ResultSet rs=st.executeQuery("SELECT * FROM tbl_test1 WHERE grp='/"+id+"/'");
					while(rs.next()){

					}
					rs.close();
					break;
				}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}